#endif
#include <string.h>
+#include <cairo-gobject.h>
#include "gtkintl.h"
#include "gtkbutton.h"
};
/* TreeModel Columns
- *
- * keep in line with the store defined in gtkfilechooserbutton.ui
*/
enum
{
GtkFileChooser *chooser; /* Points to either dialog or native, depending on which is set */
GtkWidget *dialog; /* Set if you explicitly enable */
GtkFileChooserNative *native; /* Otherwise this is set */
+ GtkWidget *box;
GtkWidget *button;
GtkWidget *image;
GtkWidget *label;
GtkCellRenderer *icon_cell;
GtkCellRenderer *name_cell;
+ /* Currently visible child (either priv->combo_box or priv->button) */
+ GtkWidget *child;
+
GtkTreeModel *model;
GtkTreeModel *filter_model;
GtkSelectionData *data,
guint type,
guint drag_time);
-static void gtk_file_chooser_button_show_all (GtkWidget *widget);
static void gtk_file_chooser_button_show (GtkWidget *widget);
static void gtk_file_chooser_button_hide (GtkWidget *widget);
static void gtk_file_chooser_button_map (GtkWidget *widget);
* GType Declaration *
* ******************* */
-G_DEFINE_TYPE_WITH_CODE (GtkFileChooserButton, gtk_file_chooser_button, GTK_TYPE_BOX,
+G_DEFINE_TYPE_WITH_CODE (GtkFileChooserButton, gtk_file_chooser_button, GTK_TYPE_WIDGET,
G_ADD_PRIVATE (GtkFileChooserButton)
G_IMPLEMENT_INTERFACE (GTK_TYPE_FILE_CHOOSER,
gtk_file_chooser_button_file_chooser_iface_init))
-/* ***************** *
- * GType Functions *
- * ***************** */
+
+static void
+gtk_file_chooser_button_measure (GtkWidget *widget,
+ GtkOrientation orientation,
+ int for_size,
+ int *minimum,
+ int *natural,
+ int *minimum_baseline,
+ int *natural_baseline)
+{
+ GtkFileChooserButton *button = GTK_FILE_CHOOSER_BUTTON (widget);
+ GtkFileChooserButtonPrivate *priv = gtk_file_chooser_button_get_instance_private (button);
+
+ gtk_widget_measure (priv->child, orientation, for_size,
+ minimum, natural,
+ minimum_baseline, natural_baseline);
+}
+
+static void
+gtk_file_chooser_button_snapshot (GtkWidget *widget,
+ GtkSnapshot *snapshot)
+{
+ GtkFileChooserButton *button = GTK_FILE_CHOOSER_BUTTON (widget);
+ GtkFileChooserButtonPrivate *priv = gtk_file_chooser_button_get_instance_private (button);
+
+ gtk_widget_snapshot_child (widget, priv->child, snapshot);
+}
+
+static void
+gtk_file_chooser_button_size_allocate (GtkWidget *widget,
+ GtkAllocation *allocation)
+{
+ GtkFileChooserButton *button = GTK_FILE_CHOOSER_BUTTON (widget);
+ GtkFileChooserButtonPrivate *priv = gtk_file_chooser_button_get_instance_private (button);
+
+ gtk_widget_size_allocate (priv->child, allocation);
+}
static void
gtk_file_chooser_button_class_init (GtkFileChooserButtonClass * class)
widget_class->destroy = gtk_file_chooser_button_destroy;
widget_class->drag_data_received = gtk_file_chooser_button_drag_data_received;
- widget_class->show_all = gtk_file_chooser_button_show_all;
widget_class->show = gtk_file_chooser_button_show;
widget_class->hide = gtk_file_chooser_button_hide;
widget_class->map = gtk_file_chooser_button_map;
widget_class->screen_changed = gtk_file_chooser_button_screen_changed;
widget_class->mnemonic_activate = gtk_file_chooser_button_mnemonic_activate;
widget_class->state_flags_changed = gtk_file_chooser_button_state_flags_changed;
+ widget_class->measure = gtk_file_chooser_button_measure;
+ widget_class->size_allocate = gtk_file_chooser_button_size_allocate;
+ widget_class->snapshot = gtk_file_chooser_button_snapshot;
/**
* GtkFileChooserButton::file-set:
_gtk_file_chooser_install_properties (gobject_class);
- /* Bind class to template
- */
- gtk_widget_class_set_template_from_resource (widget_class,
- "/org/gtk/libgtk/ui/gtkfilechooserbutton.ui");
-
- gtk_widget_class_bind_template_child_private (widget_class, GtkFileChooserButton, model);
- gtk_widget_class_bind_template_child_private (widget_class, GtkFileChooserButton, button);
- gtk_widget_class_bind_template_child_private (widget_class, GtkFileChooserButton, image);
- gtk_widget_class_bind_template_child_private (widget_class, GtkFileChooserButton, label);
- gtk_widget_class_bind_template_child_private (widget_class, GtkFileChooserButton, combo_box);
- gtk_widget_class_bind_template_child_private (widget_class, GtkFileChooserButton, icon_cell);
- gtk_widget_class_bind_template_child_private (widget_class, GtkFileChooserButton, name_cell);
-
- gtk_widget_class_bind_template_callback (widget_class, button_clicked_cb);
- gtk_widget_class_bind_template_callback (widget_class, combo_box_changed_cb);
- gtk_widget_class_bind_template_callback (widget_class, combo_box_notify_popup_shown_cb);
-
gtk_widget_class_set_css_name (widget_class, "filechooserbutton");
}
gtk_file_chooser_button_init (GtkFileChooserButton *button)
{
GtkFileChooserButtonPrivate *priv;
+ GtkWidget *box;
+ GtkWidget *icon;
GtkTargetList *target_list;
+ gtk_widget_set_has_window (GTK_WIDGET (button), FALSE);
+
priv = button->priv = gtk_file_chooser_button_get_instance_private (button);
priv->icon_size = FALLBACK_ICON_SIZE;
- gtk_widget_init_template (GTK_WIDGET (button));
+ priv->button = gtk_button_new ();
+ g_signal_connect (priv->button, "clicked", G_CALLBACK (button_clicked_cb), button);
+ priv->image = gtk_image_new ();
+ priv->label = gtk_label_new (_(FALLBACK_DISPLAY_NAME));
+ gtk_label_set_xalign (GTK_LABEL (priv->label), 0.0f);
+ gtk_widget_set_hexpand (priv->label, TRUE);
+ icon = gtk_image_new_from_icon_name ("document-open-symbolic", GTK_ICON_SIZE_BUTTON);
+ box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
+ gtk_widget_set_valign (priv->image, GTK_ALIGN_BASELINE);
+ gtk_container_add (GTK_CONTAINER (box), priv->image);
+ gtk_widget_set_valign (priv->label, GTK_ALIGN_BASELINE);
+ gtk_container_add (GTK_CONTAINER (box), priv->label);
+ gtk_widget_set_valign (icon, GTK_ALIGN_BASELINE);
+ gtk_container_add (GTK_CONTAINER (box), icon);
+ gtk_container_add (GTK_CONTAINER (priv->button), box);
+
+ gtk_widget_set_parent (priv->button, GTK_WIDGET (button));
+
+
+ priv->model = GTK_TREE_MODEL (gtk_list_store_new (NUM_COLUMNS,
+ CAIRO_GOBJECT_TYPE_SURFACE,
+ G_TYPE_STRING,
+ G_TYPE_CHAR,
+ G_TYPE_POINTER,
+ G_TYPE_BOOLEAN,
+ G_TYPE_POINTER));
+
+ priv->combo_box = gtk_combo_box_new ();
+ g_signal_connect (priv->combo_box, "changed", G_CALLBACK (combo_box_changed_cb), button);
+ g_signal_connect (priv->combo_box, "notify::popup-shown", G_CALLBACK (combo_box_notify_popup_shown_cb), button);
+ priv->icon_cell = gtk_cell_renderer_pixbuf_new ();
+ priv->name_cell = gtk_cell_renderer_text_new ();
+ g_object_set (priv->name_cell,
+ "xpad", 6,
+ NULL);
+
+ gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (priv->combo_box), priv->icon_cell, FALSE);
+ gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (priv->combo_box),
+ priv->icon_cell, "surface", 0, NULL);
+
+ gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (priv->combo_box), priv->name_cell, FALSE);
+ gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (priv->combo_box),
+ priv->name_cell, "text", 1, NULL);
+
+
+ gtk_widget_set_parent (priv->combo_box, GTK_WIDGET (button));
+
+ priv->child = priv->button;
/* Bookmarks manager */
priv->bookmarks_manager = _gtk_bookmarks_manager_new (bookmarks_changed_cb, button);
switch (g_value_get_enum (value))
{
case GTK_FILE_CHOOSER_ACTION_OPEN:
- gtk_widget_hide (priv->combo_box);
- gtk_widget_show (priv->button);
+ priv->child = priv->button;
+ gtk_widget_queue_resize (GTK_WIDGET (button));
break;
case GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER:
- gtk_widget_hide (priv->button);
- gtk_widget_show (priv->combo_box);
+ priv->child = priv->combo_box;
+ gtk_widget_queue_resize (GTK_WIDGET (button));
break;
default:
g_assert_not_reached ();
if (priv->current_folder_while_inactive)
g_object_unref (priv->current_folder_while_inactive);
+ gtk_widget_unparent (priv->button);
+ gtk_widget_unparent (priv->combo_box);
+
G_OBJECT_CLASS (gtk_file_chooser_button_parent_class)->finalize (object);
}
{
GtkFileChooserButton *button = GTK_FILE_CHOOSER_BUTTON (widget);
GtkFileChooserButtonPrivate *priv = button->priv;
- GtkWidget *child;
-
- if (gtk_widget_get_visible (priv->button))
- child = priv->button;
- else
- child = priv->combo_box;
if (gtk_widget_get_state_flags (widget) & GTK_STATE_FLAG_DROP_ACTIVE)
- gtk_widget_set_state_flags (child, GTK_STATE_FLAG_DROP_ACTIVE, FALSE);
+ gtk_widget_set_state_flags (priv->child, GTK_STATE_FLAG_DROP_ACTIVE, FALSE);
else
- gtk_widget_unset_state_flags (child, GTK_STATE_FLAG_DROP_ACTIVE);
+ gtk_widget_unset_state_flags (priv->child, GTK_STATE_FLAG_DROP_ACTIVE);
GTK_WIDGET_CLASS (gtk_file_chooser_button_parent_class)->state_flags_changed (widget, previous_state);
}
{
GtkFileChooserButton *button = GTK_FILE_CHOOSER_BUTTON (widget);
GtkFileChooserButtonPrivate *priv = button->priv;
- GtkTreeIter iter;
GSList *l;
if (priv->dialog != NULL)
priv->chooser = NULL;
- if (priv->model && gtk_tree_model_get_iter_first (priv->model, &iter))
- {
- do
- model_free_row_data (button, &iter);
- while (gtk_tree_model_iter_next (priv->model, &iter));
- }
-
if (priv->dnd_select_folder_cancellable)
{
g_cancellable_cancel (priv->dnd_select_folder_cancellable);
gtk_drag_finish (context, TRUE, FALSE, drag_time);
}
-static void
-gtk_file_chooser_button_show_all (GtkWidget *widget)
-{
- gtk_widget_show (widget);
-}
-
static void
gtk_file_chooser_button_show (GtkWidget *widget)
{
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<interface domain="gtk30">
- <!-- interface-requires gtk+ 3.10 -->
- <template class="GtkFileChooserButton" parent="GtkBox">
- <child>
- <object class="GtkButton" id="button">
- <property name="visible">1</property>
- <property name="can-focus">1</property>
- <property name="receives-default">1</property>
- <signal name="clicked" handler="button_clicked_cb" swapped="no"/>
- <style>
- <class name="file"/>
- </style>
- <child>
- <object class="GtkBox" id="box2">
- <property name="visible">1</property>
- <property name="spacing">4</property>
- <child>
- <object class="GtkImage" id="image">
- <property name="visible">1</property>
- <property name="icon-name">image-missing</property>
- </object>
- <packing>
- <property name="fill">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="label">
- <property name="visible">1</property>
- <property name="halign">start</property>
- <property name="valign">baseline</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">(None)</property>
- <property name="ellipsize">end</property>
- </object>
- <packing>
- <property name="expand">1</property>
- <property name="position">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkSeparator" id="separator1">
- <property name="visible">1</property>
- <property name="orientation">vertical</property>
- </object>
- <packing>
- <property name="fill">0</property>
- <property name="position">2</property>
- </packing>
- </child>
- <child>
- <object class="GtkImage" id="open_file_icon">
- <property name="visible">1</property>
- <property name="icon-name">document-open-symbolic</property>
- <property name="icon-size">1</property>
- <property name="use-fallback">1</property>
- <property name="valign">baseline</property>
- </object>
- <packing>
- <property name="fill">0</property>
- <property name="position">3</property>
- </packing>
- </child>
- </object>
- </child>
- </object>
- <packing>
- <property name="expand">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkComboBox" id="combo_box">
- <property name="visible">1</property>
- <signal name="changed" handler="combo_box_changed_cb" swapped="no"/>
- <signal name="notify::popup-shown" handler="combo_box_notify_popup_shown_cb" swapped="no"/>
- <child>
- <object class="GtkCellRendererPixbuf" id="icon_cell"/>
- <attributes>
- <attribute name="surface">0</attribute>
- </attributes>
- </child>
- <child>
- <object class="GtkCellRendererText" id="name_cell">
- <property name="xpad">6</property>
- </object>
- <attributes>
- <attribute name="text">1</attribute>
- </attributes>
- </child>
- </object>
- <packing>
- <property name="expand">1</property>
- <property name="position">1</property>
- </packing>
- </child>
- </template>
- <object class="GtkListStore" id="model">
- <columns>
- <!-- column-name icon -->
- <column type="CairoSurface"/>
- <!-- column-name display-name -->
- <column type="gchararray"/>
- <!-- column-name type -->
- <column type="gchar"/>
- <!-- column-name data -->
- <column type="gpointer"/>
- <!-- column-name is-folder -->
- <column type="gboolean"/>
- <!-- column-name cancelable -->
- <column type="gpointer"/>
- </columns>
- </object>
-</interface>